<html>
  <head>
    <title>Aladino</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        font-family: "Arial", serif;
      }

      * {
        box-sizing: border-box;
      }

      .wrapper {
        width: 100%;
        padding: 0 40px;
        max-width: 900px;
        margin: 0 auto;
      }

      article {
        width: 100%;
        height: 0;
        padding-bottom: 60%;
        background: red;
        margin: 50px 0;
      }

      button {
        font-size: 20px;
        padding: 20px;
        cursor: pointer;
        border: 0;
        background-color: black;
        color: white;
        margin-bottom: 50px;
      }

      button.aladino {
        opacity: 1 !important;
        background: transparent;
      }

      h1 {
        font-size: 20px;
      }

      canvas {
        z-index: -1;
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <div style="height: 50px"></div>
      <h1>Hi there, this is a `button`:</h1>

      <button>
        <span>Click here</span>
      </button>

      <h1>This is the same button, with aladino:</h1>

      <button class="button-1">
        <span>Click here</span>
      </button>

      <h1>wireframe debug:</h1>
      <button class="button-2">
        <span>Click here</span>
      </button>

      <h1>displacement + uv:</h1>
      <button class="button-3">
        <span>Click here</span>
      </button>

      <h1>texture:</h1>
      <button class="button-4" data-image="https://source.unsplash.com/random">
        <span>Click here</span>
      </button>

      <h1>hover:</h1>
      <button class="button-5">
        <span>Click here</span>
      </button>

      <h1>hover 2:</h1>
      <button class="button-6">
        <span>Click here</span>
      </button>
    </div>

    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.5/gsap.min.js"
      type="text/javascript"
    ></script>

    <script type="module">
      import Aladino from "./src/index.js";

      const aladino = new Aladino({
        density: 10,
      });

      document.body.appendChild(aladino.canvas);

      aladino.carpet(document.querySelector(".button-1"), {
        material: aladino.material(),
      });

      aladino.carpet(document.querySelector(".button-2"), {
        material: aladino.material(),
        wireframe: true,
        scale: [2, 1],
      });

      aladino.carpet(document.querySelector(".button-3"), {
        material: aladino.material({
          vertex: /* glsl */ `
          attribute vec2 position;
          attribute vec2 uv;

          uniform mat4 projection;
          uniform float time;

          varying vec2 vUv;

          void main() {
            vUv = uv;
            float p = sin(time * 0.003 + uv.y * 4. + uv.x * .3) * .2;

            float scale = ((sin(time * 0.003) + 1.0) / 2.0) * .4 + 1.0;
            gl_Position = projection * vec4(position * scale, p, 1.0);
          }
        `,
          fragment: /* glsl */ `
          precision highp float;

          varying vec2 vUv;

          void main() {
            gl_FragColor = vec4(vUv, 0.0, 1.0);
          }
        `,
        }),
        position: [100, 0],
        scale: [1.1, 1],
      });

      aladino.carpet(document.querySelector(".button-4"), {
        material: aladino.material({
          vertex: /* glsl */ `
            attribute vec2 position;
            attribute vec2 uv;

            uniform mat4 projection;
            uniform float time;

            varying vec2 vUv;

            void main() {
              vUv = uv;
              float p = sin(time * 0.003 + uv.y * 3. + uv.x * 2.0) * .2;
              gl_Position = projection * vec4(position, p, 1.0);
            }
          `,
          fragment: /* glsl */ `
            precision highp float;

            uniform sampler2D image;
            varying vec2 vUv;

            void main() {
              gl_FragColor = texture2D(image, vUv);
            }
          `,
          uniforms: {
            image: aladino.texture(
              document.querySelector(".button-4").dataset.image
            ),
          },
        }),
      });

      const button5 = document.querySelector(".button-5");
      const carpet5 = aladino.carpet(button5, {
        material: aladino.material({
          vertex: /* glsl */ `
            attribute vec2 position;
            attribute vec2 uv;

            uniform mat4 projection;
            uniform float time;
            uniform float hover;

            varying vec2 vUv;

            float parabola(float x, float k) {
              return pow(4.0*x*(1.0-x), k);
            }

            void main() {
              vUv = uv;
              vec4 pos = vec4(position, 0.0, 1.0);

              pos.xyz *= 1.0 + ((parabola(uv.x, 1.4) * .3) * hover);

              gl_Position = projection * pos;
            }`,
          fragment: /* glsl */ `
            precision highp float;

            void main() {
              gl_FragColor = vec4(0, 0.0, 0.0, 1.0);
            }
          `,
        }),
        uniforms: {
          hover: 0,
        },
      });

      button5.addEventListener("mouseenter", () => {
        gsap.killTweensOf(carpet5.uniforms);
        gsap.to(carpet5.uniforms, {
          hover: 1,
          duration: 1,
          ease: "elastic.out(1, 0.3)",
        });
      });

      button5.addEventListener("mouseleave", () => {
        gsap.killTweensOf(carpet5.uniforms);
        gsap.to(carpet5.uniforms, {
          hover: 0,
          duration: 2,
          ease: "elastic.out(1, 0.18)",
        });
      });

      // Button 6
      const button6 = document.querySelector(".button-6");
      const carpet6 = aladino.carpet(button6, {
        material: aladino.material({
          vertex: /* glsl */ `
            attribute vec2 position;
            attribute vec2 uv;

            uniform mat4 projection;
            varying vec2 vUv;

            void main() {
              vUv = uv;

              vec4 pos = vec4(position, 0.0, 1.0);
              gl_Position = projection * pos;
            }
          `,
          fragment: /* glsl */ `
          precision highp float;

          uniform float time;
          uniform float hover;
          varying vec2 vUv;

          vec3 mod289(vec3 x) {
              return x - floor(x * (1.0 / 289.0)) * 289.0;
          }
          vec4 mod289(vec4 x) {
              return x - floor(x * (1.0 / 289.0)) * 289.0;
          }
          vec4 permute(vec4 x) {
              return mod289(((x*34.0)+1.0)*x);
          }
          vec4 taylorInvSqrt(vec4 r) {
              return 1.79284291400159 - 0.85373472095314 * r;
          }
          float snoise(vec3 v) {
              const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;
              const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);
              
              // First corner
              
              vec3 i = floor(v + dot(v, C.yyy) );
              vec3 x0 = v - i + dot(i, C.xxx) ;
              
              // Other corners
              
              vec3 g = step(x0.yzx, x0.xyz);
              vec3 l = 1.0 - g;
              vec3 i1 = min( g.xyz, l.zxy );
              vec3 i2 = max( g.xyz, l.zxy );
              
              //   x0 = x0 - 0.0 + 0.0 * C.xxx;
              
              //   x1 = x0 - i1  + 1.0 * C.xxx;
              //   x2 = x0 - i2  + 2.0 * C.xxx;
              //   x3 = x0 - 1.0 + 3.0 * C.xxx;
              vec3 x1 = x0 - i1 + C.xxx;
              vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
              
              vec3 x3 = x0 - D.yyy;      // -1.0+3.0*C.x = -0.5 = -D.y
              
              
              // Permutations
              i = mod289(i);
              vec4 p = permute( permute( permute(
              i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
              + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
              + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
              
              // Gradients: 7x7 points over a square, mapped onto an octahedron.
              
              // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
              float n_ = 0.142857142857; // 1.0/7.0
              
              vec3  ns = n_ * D.wyz - D.xzx;
              vec4 j = p - 49.0 * floor(p * ns.z * ns.z);  //  mod(p, 7*7)
              
              
              vec4 x_ = floor(j * ns.z);
              vec4 y_ = floor(j - 7.0 * x_ );    // mod(j, N)
              
              
              vec4 x = x_ *ns.x + ns.yyyy;
              vec4 y = y_ *ns.x + ns.yyyy;
              vec4 h = 1.0 - abs(x) - abs(y);
              vec4 b0 = vec4( x.xy, y.xy );
              vec4 b1 = vec4( x.zw, y.zw );
              
              //vec4 s0 = vec4(lessThan(b0, 0.0))*2.0 - 1.0;
              
              //vec4 s1 = vec4(lessThan(b1, 0.0))*2.0 - 1.0;
              vec4 s0 = floor(b0)*2.0 + 1.0;
              vec4 s1 = floor(b1)*2.0 + 1.0;
              vec4 sh = -step(h, vec4(0.0));
              vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
              vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
              vec3 p0 = vec3(a0.xy, h.x);
              vec3 p1 = vec3(a0.zw, h.y);
              vec3 p2 = vec3(a1.xy, h.z);
              vec3 p3 = vec3(a1.zw, h.w);
              
              //Normalise gradients
              
              vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
              p0 *= norm.x;
              p1 *= norm.y;
              p2 *= norm.z;
              p3 *= norm.w;
              
              // Mix final noise value
              
              vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
              m = m * m;
              return 42.0 * dot( m*m, vec4( dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3) ) );
          }

          void main() {
            vec4 color = vec4(0.0, 0.0, 0.0, 1.0);

            float total = 0.0;
            vec3 pos = vec3(vUv.xy * 4.0, time * 0.0004);
            float adjust;
            for(float i = 0.0; i < 3.0; i++) {
                // octaves
                float frequency = pow(4.2, i);
                float amplitude = pow(0.4, i);
                adjust += amplitude;
                total += snoise(pos * frequency) * amplitude;
            }
            
            // float n = noise(vec3(vUv.x * 8.0 + time * 0.004, vUv.y * 4.0, time * 0.001));
            color = mix(color, vec4(1.0), total + hover);

            gl_FragColor = color;
          }
        `,
        }),
        uniforms: {
          hover: 0,
        },
      });

      button6.addEventListener("mouseenter", () => {
        gsap.killTweensOf(carpet6.uniforms);
        gsap.to(carpet6.uniforms, {
          hover: 1,
          duration: 1,
          ease: "elastic.out(1, 0.3)",
        });
      });

      button6.addEventListener("mouseleave", () => {
        gsap.killTweensOf(carpet6.uniforms);
        gsap.to(carpet6.uniforms, {
          hover: 0,
          duration: 2,
          ease: "elastic.out(1, 0.18)",
        });
      });
    </script>
  </body>
</html>
